package com.my.study.reflection;

import com.my.study.reflection.utils.Resolver;

import java.lang.annotation.Annotation;
import java.util.Set;

/**
 * @author: yidujun
 * @create: 2021/07/16 10:50
 */
public class ResolverUtils {

    private ResolverUtils() {}

    /**
     * 扫描指定包以及子包，获取{@code parent}子类或实现类
     *
     * @param parent 超类
     * @param packNames 权限定名
     * @return Set<Class<?>>
     */
    public static Set<Class<?>> findImpl(Class<?> parent, String... packNames) {
        return find(parent, Option.IMPLEMENT, packNames);
    }

    /**
     * 扫描指定包以及子包，获取注解了注解{@code annotation}的类
     *
     * @param annotation 注解
     * @param packNames 权限定名
     * @return Set<Class<?>>
     */
    public static Set<Class<?>> findAnnotation(Class<?> annotation, String... packNames) {
        return find(annotation, Option.ANNOTATION, packNames);
    }

    @SuppressWarnings("unchecked")
    public static Set<Class<?>> find(Class<?> parent, Option option, String... packNames) {
        Resolver<?> resolver = new Resolver<>();
        if (Option.IMPLEMENT == option) {
            resolver.findImplementations(parent, packNames);
        } else {
            resolver.findAnnotated((Class<? extends Annotation>) parent, packNames);
        }

        Set<Class<?>> classes = (Set<Class<?>>) resolver.getClasses();

        if (Option.IMPLEMENT == option) {
            classes.remove(parent);
        }

        return classes;
    }


    public enum Option {
        /** 继承或实现类型 */
        IMPLEMENT,
        /** 注解类型 */
        ANNOTATION;
    }

}
